#include "ExecuteEngine.h"
#include "method.h"
#include "Class.h"
#include "attribute_info.h"
#include "string"
#include "types.h"
#include "frame.h"
#include <stack>
using namespace std;

void ExecuteEngine(Class *javaClass, Method *method, Frame *frame) {
	code_attribute *codeAttribute;
	for(int i = 0; i < method->attributes_count; i++) {
		short nameIndex = method->attributes[i]->attribute_name_index;
		if(javaClass->constant_pool[nameIndex] == L'Code'){
			codeAttribute = method->attributes[i];
			break;
		}
	}

	while(frame->pc < codeAttribute->code_length) {
		U1 code = codeAttribute->code[frame->pc];
		switch(code) {
			case nop:/*0*/
				frame->pc++;
				break;
			case aconst_null:/*1*/
				frame->opStack.push(null);
				break;
			case iconst_m1:
			case iconst_0:
			case iconst_1:
			case iconst_2:
			case iconst_3:
			case iconst_4:
			case iconst_5:
				frame->pc++;
				Variable v;
				v.intValue = U4(code - iconst_0);
				frame->opStack.push(v);
				break;
			case lconst_0:
			case lconst_1:
				frame->pc++;
				Variable v;
				v.longValue = LONG64(code - lconst_0);
				frame->opStack.push(v);
				break;
			case fconst_0:
			case fconst_1:
			case fconst_2:
				frame->pc++;
				Variable v;
				v.floatValue = f4((code - fconst_0)*1.0);
				frame->opStack.push(v);
				break;
			case dconst_0:
			case dconst_1:
				frame->pc++;
				Variable v;
				v.doubleValue = f8((code - dconst_0)*1.0);
				break;
			case bipush:
				frame->pc++;
				Variable v;
				U1 c = codeAttribute->code[frame->pc];
				v.intValue = S1(c);
				frame->opStack.push(v);
				frame->pc++;
				break;
			case sipush:
				frame->pc++;
				Variable v;
				U2 c1 = (codeAttribute->code[frame->pc] & 0x00FF);
				frame->pc++;
				U2 c2 = (codeAttribute->code[frame->pc] & 0x00FF);
				frame->pc++;
				v.intValue = S4(c1 << 8 | c2);
				frame->opStack.push(v);
				break;
			/*case ldc:
				frame->pc++;
				U1 index = codeAttribute->code[frame->pc];
				frame->pc++;
				Variable v;
				cp_info *cp = javaClass->constant_pool[index];
				if(cp->tag == CONSTANT_Integer) {
					v.intValue = ((constant_integer_info*)cp)->bytes;
					frame->opStack.push(v);
				}else if(cp->tag == CONSTANT_Float){
					v.intValue = (((constant_float_info*)cp)->bytes);
					frame->opStack.push(v);
				}else if(cp->tag == CONSTANT_String){
					v.stringValue = 
				}
				break;*/
		}
		
	}
}